﻿using System;
using Adventure.Server.Library;
using Adventure.Tests.Properties;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Adventure.Tests
{
    /// <summary>
    /// Tests the SavedObject class.
    /// </summary>
    [TestClass]
    public class SavedObjectTests
    {
        /// <summary>
        /// Tests the creation of a SavedObject with a limited classname.
        /// </summary>
        [TestMethod]
        public void SavedObjectCreationTests()
        {
            // "Adventure.Server.Library.SavedObject, Adventure.Server, Version=0.1.0.1, Culture=neutral, PublicKeyToken=16d3329393ccd055";
            string classname = "Adventure.Server.Library.SavedObject, Adventure.Server";
            
            var attributes = new ObjectAttributes
            {
                [SavedObject.ClassNameAttribute] = classname,
                [SavedObject.IdentifierAttribute] = "id1"
            };
            Assert.IsNotNull(SavedObject.Create(attributes));

            // Check automatically build classnames without Version, Culture and Public Key!
            classname = typeof(SavedObject).FullName + ", " + typeof(SavedObject).Assembly.GetName().Name;
            attributes[SavedObject.ClassNameAttribute] = classname;
            Assert.IsNotNull(SavedObject.Create(attributes));
        }

        /// <summary>
        /// Tests the comparing of saved objects.
        /// </summary>
        [TestMethod]
        public void SavedObjectsCompareTests()
        {
            var attributes = new ObjectAttributes
            {
                [SavedObject.ClassNameAttribute] = typeof(SavedObject).AssemblyQualifiedName,
                [SavedObject.IdentifierAttribute] = "id1"
            };
            var obj1 = SavedObject.Create(attributes);
            var obj2 = SavedObject.Create(attributes);
            attributes[SavedObject.IdentifierAttribute] = "id2";
            var obj3 = SavedObject.Create(attributes);
            Assert.AreEqual(obj1, obj2);
            Assert.AreEqual(obj1.GetHashCode(), obj2.GetHashCode());
            Assert.AreNotEqual(obj1, obj3);
            Assert.AreNotEqual(obj1.GetHashCode(), obj3.GetHashCode());
        }

        /// <summary>
        /// Tests the creation of SavedObjects
        /// </summary>
        [TestMethod]
        public void CreateSavedObjectInstanceTests()
        {
            // Set attributes for new SavedObject
            var id = Settings.Default.TestObjectId;
            var attributes = HelperFunctions.CreateAttributes(id);

            // Create a new instance of a SavedObject
            SavedObject obj;
            using (obj = SavedObject.Create(attributes))
            {
                Assert.IsNotNull(obj);
                Assert.AreEqual(1,obj.ReferenceCounter);
            }

            // Try to create an instance of a non existing class
            attributes[SavedObject.ClassNameAttribute] = "DoesNotExist";
            Assert.IsNull(SavedObject.Create(attributes));

            // Test that save does not work (ObjectManager shouldn't be set)
            try
            {
                obj.Save();
                Assert.Fail("An exception should be thrown because there is no ObjectManager set.");
            }
            catch (Exception)
            {
                // Nothing to do.
            }

            // Check the Reference Counter of SavedObjects
            Assert.AreEqual(0, obj.ReferenceCounter);
        }
    }
}
